package com.asiainfo.integration.tibco;

import com.asiainfo.integration.utils.tibjmsUtilities;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Properties;

public class TestReadMessageFromQueue implements ExceptionListener, MessageListener {

    String serverUrl = null;

    String userName = null;

    String password;

    String name;

    String fileName;

    String productLocalPath;

    String productBackupPath;

    Connection connection = null;

    Session session = null;

    MessageConsumer msgConsumer = null;

    Destination destination = null;

    static int iCount = 0;

    static Logger log = Logger.getLogger(TestReadMessageFromQueue.class.getName());

    public static void main(String[] args) {
        new TestReadMessageFromQueue(args);
    }

    public TestReadMessageFromQueue(String[] args) {
        try {
            Properties props = new Properties();
            InputStream in = this.getClass().getResourceAsStream("/config/queue/config.properties");
            props.load(in);
            serverUrl = props.get("jms_server_url").toString();
            userName = props.get("jms_server_usr_name").toString();
            password = props.get("jms_server_usr_pwd").toString();
            name = props.get("jms_server_queue_name").toString();
            fileName = props.get("fileName").toString();
            String connectionFactory = props.get("jms_server_conn_fct").toString();
            productLocalPath = props.get("productLocalPath").toString();
            productBackupPath = props.get("productBackupPath").toString();
            String initialContextFactory = props.get("initial_context_factory").toString();

            tibjmsUtilities.initSSLParams(serverUrl, args);

            Hashtable<String, String> environment = new Hashtable<String, String>();
            environment.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
            environment.put(Context.PROVIDER_URL, serverUrl);
            environment.put(Context.SECURITY_PRINCIPAL, userName);
            environment.put(Context.SECURITY_CREDENTIALS, password);
            InitialContext ctx = new InitialContext(environment);
            ConnectionFactory factory = (ConnectionFactory) ctx.lookup(connectionFactory);

            /* create the connection */
            connection = factory.createConnection(userName, password);

            /* create the session */
            session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);

            /* set the exception listener */
            connection.setExceptionListener(this);

            /* create the destination */
            /*
             * if(useTopic) destination = session.createTopic(name); else
             */
            destination = session.createQueue(name);

            System.err.println("Subscribing to destination: " + name);

            /* create the consumer */
            msgConsumer = session.createConsumer(destination);

            /* set the message listener */
            msgConsumer.setMessageListener(this);

            /* start the connection */
            connection.start();

            // when message callback is used, the session
            // creates the dispatcher thread which is not a daemon
            // thread by default. Thus we can quit this method however
            // the application will keep running. It is possible to
            // specify that all session dispatchers are daemon threads.
        } catch (JMSSecurityException e) {
            System.err.println("JMSSecurityException: " + e.getMessage() + ", provider=" + e.getErrorCode());
            e.printStackTrace();
            System.exit(0);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JMSException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    /*-----------------------------------------------------------------------
     * usage
     *----------------------------------------------------------------------*/
    void usage() {
        System.err.println("\nUsage: java tibjmsAsyncMsgConsumer [options] [ssl options]");
        System.err.println("\n");
        System.err.println("   where options are:\n");
        System.err.println("\n");
        System.err.println(" -server   <server URL> - EMS server URL, default is local server\n");
        System.err.println(" -user     <user name>  - user name, default is null\n");
        System.err.println(" -password <password>   - password, default is null\n");
        System.err.println(" -topic    <topic-name> - topic name, default is \"topic.sample\"\n");
        System.err.println(" -queue    <queue-name> - queue name, no default\n");
        System.err.println(" -help-ssl              - help on ssl parameters\n");
        System.exit(0);
    }

    /*-----------------------------------------------------------------------
     * parseArgs
     *----------------------------------------------------------------------*/
    void parseArgs(String[] args) {
        int i = 0;

        while (i < args.length) {
            if (args[i].compareTo("-server") == 0) {
                if ((i + 1) >= args.length)
                    usage();
                serverUrl = args[i + 1];
                i += 2;
            } else if (args[i].compareTo("-topic") == 0) {
                if ((i + 1) >= args.length)
                    usage();
                name = args[i + 1];
                i += 2;
            } else if (args[i].compareTo("-queue") == 0) {
                if ((i + 1) >= args.length)
                    usage();
                name = args[i + 1];
                i += 2;
                // useTopic = false;
            } else if (args[i].compareTo("-user") == 0) {
                if ((i + 1) >= args.length)
                    usage();
                userName = args[i + 1];
                i += 2;
            } else if (args[i].compareTo("-password") == 0) {
                if ((i + 1) >= args.length)
                    usage();
                password = args[i + 1];
                i += 2;
            } else if (args[i].compareTo("-help") == 0) {
                usage();
            } else if (args[i].compareTo("-help-ssl") == 0) {
                tibjmsUtilities.sslUsage();
            } else if (args[i].startsWith("-ssl")) {
                i += 2;
            } else {
                System.err.println("Unrecognized parameter: " + args[i]);
                usage();
            }
        }
    }

    /*---------------------------------------------------------------------
     * onException
     *---------------------------------------------------------------------*/
    public void onException(JMSException e) {
        /* print the connection exception status */
        System.err.println("CONNECTION EXCEPTION: " + e.getMessage());
    }

    private void sleepForSomeTime() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }

    /*---------------------------------------------------------------------
     * onMessage
     *---------------------------------------------------------------------*/
    public void onMessage(Message msg) {
        boolean flag = false;
        try {
            // Save File to Disc
            iCount += 1;
            System.out.println("iCount=================: " + iCount);
            TextMessage textM = (TextMessage) msg;

            System.out.println("Received message: " + textM.getText());

            String msgProduct = textM.getText();

            if (StringUtils.isBlank(msgProduct)) {
                log.error(" ######### No Product Xml Need load To DIB #########");
                return;
            }
            /*##################tibco send mssage transfer to disk ########################*/
            /*if (msgProduct.indexOf("?xml version=") != -1
                    && msgProduct.indexOf("AllowedBusinessInteractionMapping") != -1
					&& msgProduct.indexOf("PlanOffering") != -1
					&& msgProduct.indexOf("PlanSpecification") != -1
					&& msgProduct.indexOf("Identifier") != -1
					&& msgProduct.indexOf("ProductOffering") != -1
					&& msgProduct.indexOf("ResourceSpecification") != -1
					&& msgProduct.indexOf("PlanSpecification") != -1
					&& msgProduct.indexOf("GeographicLoc") != -1
					&& msgProduct.indexOf("mpositePric") != -1) {*/
            try {
                flag = executeTransfer(msgProduct);
                System.out.println("Received message-----------------: " + flag);
            } catch (Exception e) {
                log.error(" ######### Product Xml Load To DIB Error !!! #########");
            }

			/*} else {
                log.error(" ######### not valid product xml string #########");
				return;
			}*/


            log.error(" ######### EPC Message Received from Queue #########");

            // JFT


        } catch (Exception e) {
            System.err.println("Unexpected exception in the message callback!");
            e.printStackTrace();
            System.exit(-1);
        }
    }

    private boolean executeTransfer(String msg) {
        boolean boolFlag = false;
        log.info("######### Product Xml Write Disk Begin #########");
        System.out.println("######  inside executeTransfer ######");
        String xmlFilename = fileName + "_" + getSystemDate() + ".xml";

        log.info("#########Product Xml Load  Name=" + xmlFilename
                + " #########");

        String productXmlPathString = productLocalPath + "" + xmlFilename;

        log.info("#########Write Product Xml To Load Path="
                + productXmlPathString + " #########");

        try {
            WriteStringToFile(productLocalPath, msg, xmlFilename);
        } catch (Exception e) {
            return boolFlag;
        }

        log.info("#########Product Xml Write to Disk  Success #########");
        boolFlag = true;
        return boolFlag;

    }

    private void WriteStringToFile(String filePath, String strxml,
                                   String fileName) throws Exception {
        File tmpFile = new File(filePath);
        if (!tmpFile.exists()) {
            tmpFile.mkdirs();
        }

        File file = new File(filePath + "" + fileName);

        if (file.exists()) {
            file.delete();
        }

        OutputStreamWriter out = null;
        BufferedWriter bufw = null;

        try {
            out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
            bufw = new BufferedWriter(out);//
            bufw.write(strxml.trim());
            bufw.flush();

        } catch (Exception e) {
            throw new Exception("write stringxml to xml file error...");
        } finally {
            bufw.close();
        }
    }

    private static String getSystemDate() {
        String time = "";
        Date d = new Date(System.currentTimeMillis());
        SimpleDateFormat formatter = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
        time = formatter.format(d);
        return time;
    }

}
